package com.better.frontend.service.scoresegment;

import com.alibaba.fastjson.JSONObject;
import com.better.backend.dataComputingService.model.point.ExamSubjectStuPointCalModel;
import com.better.backend.dataComputingService.model.point.PointCalModel;
import com.better.backend.dataComputingService.model.scoreSelection.SeleExamStudentScoreCalModel;
import com.better.backend.dataComputingService.model.scoreSelection.SeleProportion;
import com.better.backend.dataComputingService.model.scoreSelection.SeleStudentScoreCalModel;
import com.better.backend.dataComputingService.model.scoreSelection.SeleSubujectScoreCalModel;
import com.better.backend.dataComputingService.model.stuScore.ExamStudentScoreCalModel;
import com.better.backend.dataComputingService.model.stuScore.StudentScoreCalModel;
import com.better.backend.dataComputingService.repository.pointRespository.PointRepsitory;
import com.better.backend.dataComputingService.repository.scoreSelection.SeleExamStudentScoreRepsitory;
import com.better.backend.dataComputingService.repository.stuScoreRespository.ExamStuScoRepsitory;
import com.better.backend.mqReceiverService.questionReceiver.model.ExamPaperModel;
import com.better.backend.mqReceiverService.questionReceiver.repository.ExamPaperRepsitory;
import com.better.common.base.ServiceResponse;
import com.better.common.mongo.model.SpringDataPageable;
import com.better.common.utils.ServiceResponseHandle;
import com.better.consist.GlobalTypeEnum;
import com.better.frontend.Iservice.scoresegment.SegmentMangerService;
import com.better.frontend.Iservice.studentScore.StudentScoreService;
import com.better.frontend.model.scoresegment.*;
import com.better.frontend.vo.excel.ClassSementStudentExcelVo;
import com.better.frontend.vo.excel.ScoreExcelVo;
import com.better.frontend.vo.excel.ScoreSectionExcelVo;
import com.better.frontend.vo.excel.StepLineExcelVo;
import com.better.frontend.vo.scoreFootFault.ScoreFootFaultVo;
import com.better.frontend.vo.scoreFootFault.SubjectFootScoreVo;
import com.better.frontend.vo.scoresegment.ScoreSegmentVo;
import com.better.frontend.vo.scoresegment.SeleStudentScoreCalVO;
import com.better.frontend.vo.scoresegment.SubjectScoreVo;
import com.better.frontend.vo.studentScore.SubjectVo;
import com.better.util.BigDecimalUtils;
import com.better.util.FiledAliasMapUtils;
import com.better.util.excelUtil.ExcelUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by Administrator on 2017/12/1.
 */
@Service
public class SegmentMangerServiceImp implements SegmentMangerService {
    @Resource
    private SeleExamStudentScoreRepsitory seleExamStudentScoreRepsitory;
    @Resource
    private ExamPaperRepsitory examPaperRepsitory;
    @Resource
    private PointRepsitory pointRepsitory;
    @Resource
    private ExamStuScoRepsitory examStuScoRepsitory;
    @Resource
    private StudentScoreService studentScoreService;
    private static Logger logger = LoggerFactory.getLogger(SegmentMangerServiceImp.class);
    @Override
    public Page<ScoreSegmentVo> getSegment(ScoreSementParm sementParm) {
        Map<String, Object> queryMap = new HashedMap<>();
        if (sementParm != null && StringUtils.isNotEmpty(sementParm.getExamId()))
            queryMap.put("examId", sementParm.getExamId());
        if (sementParm != null && StringUtils.isNotEmpty(sementParm.getSchoolId()))
            queryMap.put("schoolId", sementParm.getSchoolId());
        if (sementParm != null && StringUtils.isNotEmpty(sementParm.getGradeId()))
            queryMap.put("gradeId", sementParm.getGradeId());
        if (sementParm != null && StringUtils.isNotEmpty(sementParm.getClassId()))
            queryMap.put("classId", sementParm.getClassId());
        SeleStudentScoreCalVO bean = new SeleStudentScoreCalVO();
        Map<String, String> filedAlias= FiledAliasMapUtils.java2Map(bean,"seleStudentScore");
       /* Map<String, String> filedAliasMap = new HashMap<>();*/
        // Map<String, String> filedAliasMap = FiledAliasMapUtils.java2Map(bean, "seleStudentScoreList");
        filedAlias.put("seleStudentScoreList", "seleStudentScore");
        SpringDataPageable pageable = new SpringDataPageable(sementParm.getPageIndex(), sementParm.getPageSize());
        Page<SeleStudentScoreCalVO> page = seleExamStudentScoreRepsitory.findNestPage(queryMap, filedAlias,null, "seleStudentScore","seleStudentScore.studentId", null,
                SeleExamStudentScoreCalModel.class, SeleStudentScoreCalVO.class);
        List<SeleStudentScoreCalVO> list = page.getContent();
        List<ScoreSegmentVo> scoreSegmentList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (SeleStudentScoreCalVO seleExam : list) {
                List<SubjectScoreVo> subjectScoreList = new ArrayList<>();
                SeleStudentScoreCalModel seleExamStudentScore = seleExam.getSeleStudentScore();
                ScoreSegmentVo scoreSegment = new ScoreSegmentVo();
                if (seleExamStudentScore != null) {
                    scoreSegment.setStudentName(seleExamStudentScore.getStudentName());//学生姓名
                    scoreSegment.setStudentNo(seleExamStudentScore.getStudentNo());//学号唯一
                    scoreSegment.setAverageScore(seleExamStudentScore.getTotalAvg());//平均分
                    scoreSegment.setTotalScore(seleExamStudentScore.getTotalScore());//总分
                    scoreSegment.setStudentId(seleExamStudentScore.getStudentId());
                    List<SeleSubujectScoreCalModel> seleStudentScoreList = seleExamStudentScore.getSeleSubujectScoreList();
                    if (CollectionUtils.isNotEmpty(seleStudentScoreList)) {
                        for (SeleSubujectScoreCalModel seleStudentScore : seleStudentScoreList) {
                            SubjectScoreVo subjectScore = new SubjectScoreVo();
                            subjectScore.setSubjectId(seleStudentScore.getSubjectId());
                            subjectScore.setScore(seleStudentScore.getScore());
                            subjectScore.setSubjectName(seleStudentScore.getSubjectName());
                            subjectScore.setScoreState(seleStudentScore.getSelectValueName());
                            subjectScoreList.add(subjectScore);
                        }
                    }
                }
                scoreSegment.setSubjectScores(subjectScoreList);
                scoreSegment.setScoreState(seleExamStudentScore.getSelectValueName());
                scoreSegmentList.add(scoreSegment);

            }
        }
        Page<ScoreSegmentVo> pages = new PageImpl<ScoreSegmentVo>(scoreSegmentList, pageable, page.getTotalElements());
        return pages;
    }

    @Override
    public <T> T historicalStatistics(ScoreSementParm scoreSementParm) {
        return null;
    }

    /**
     * 班级分析分数段统计
     * @param scoreSementParm
     * @return
     */
    @Override
    public ServiceResponse classSement(ClassSementParm scoreSementParm){
        List<SeleExamStudentScoreCalModel> list = seleExamStudentScoreRepsitory.findByExamIdAndGradeIdAndClassId(scoreSementParm.getExamId(),scoreSementParm.getGradeId(),scoreSementParm.getClassId());
        if(list==null||list.size()!=1){
            return ServiceResponseHandle.failed("查询失败！请设置分数段");
        }
        List<SeleProportion> seleProportionClassList = list.get(0).getSeleProportionClassList();
        seleProportionClassList = seleProportionClassList.stream().filter(e->!e.getSubjectId().equals("0")).collect(Collectors.toList());
        List<ClassSementVo> reList = new ArrayList<>();
        //按分数段分组
       Map<String,List<SeleProportion>> map = seleProportionClassList.stream().collect(Collectors.groupingBy(s->s.getSelectValue()));
        map.forEach((k,v)->{
          //排序,按科目名称排序
            v.sort((v1,v2)->v1.getSubjectName().compareTo(v2.getSubjectName()));
            ClassSementVo vo = new ClassSementVo();
            vo.setSementName(v.get(0).getSelectValueName());
            String[] subjectName = new String[v.size()];
            String[] subjectId = new String[v.size()];
            int[] num =new int[v.size()];
            for (int i = 0;i<v.size();i++){
                String subjectName1 = v.get(i).getSubjectName();
                if(StringUtils.isEmpty(subjectName1)){
                    continue;
                }
                subjectName[i] = v.get(i).getSubjectName();
                subjectId[i] = v.get(i).getSubjectId();
                num[i] = v.get(i).getCount();
            }
            vo.setSubjectId(subjectId);
            vo.setSubjectName(subjectName);
            vo.setNum(num);
            reList.add(vo);
        });
        return ServiceResponseHandle.success(reList);
    }

    /**
     * 班级分析分数段对比统计,总分和单科
     * @param classSementCompParm
     * @return
     */
    @Override
    public ServiceResponse classTotalAndSubSementCompare(ClassSementCompParm classSementCompParm){
        if("0".equals(classSementCompParm.getSubjectId())){
            return classSementCompare(classSementCompParm);
        }
        else {
            ClassSementCompVo reSub = classSementCompare(classSementCompParm).data;
            //设置总分
            classSementCompParm.setSubjectId("0");
            ClassSementCompVo reTot = classSementCompare(classSementCompParm).data;
            reSub.setTotalSement(reTot);
            return ServiceResponseHandle.success(reSub);
        }
    }
    /**
     * 班级分析分数段对比统计
     * @param classSementCompParm
     * @return
     */
    @Override
    public ServiceResponse<ClassSementCompVo> classSementCompare(ClassSementCompParm classSementCompParm){
        ClassSementCompVo revo = new ClassSementCompVo();
        List<SeleExamStudentScoreCalModel> listSource = seleExamStudentScoreRepsitory.findByExamIdAndGradeIdAndClassId(classSementCompParm.getSourceExamId(),classSementCompParm.getGradeId(),classSementCompParm.getClassId());
        List<SeleExamStudentScoreCalModel> listTarget = seleExamStudentScoreRepsitory.findByExamIdAndGradeIdAndClassId(classSementCompParm.getTargetExamId(),classSementCompParm.getGradeId(),classSementCompParm.getClassId());
        if(listSource==null||listTarget==null||listTarget.size()!=1||listSource.size()!=1){
            return ServiceResponseHandle.failed("查询失败！请联系管理员");
        }
        SeleExamStudentScoreCalModel sourceSele = listSource.get(0);
        SeleExamStudentScoreCalModel targetSele = listTarget.get(0);
        revo.setSourExamName(sourceSele.getExamName());
        revo.setTargetExamName(targetSele.getExamName());
        if(!calStuTable(sourceSele,targetSele,revo,classSementCompParm)){
            return ServiceResponseHandle.failed("查询失败！请联系管理员");
        }
        //筛选对应等级学生信息
        List<SeleStudentScoreCalModel> sStu = sourceSele.getSeleStudentScoreList();
        List<SeleStudentScoreCalModel> tStu = targetSele.getSeleStudentScoreList();
        //用于存放返回的学生list
        List<ClassSementStudentVo> sReList = new ArrayList<>();
        List<ClassSementStudentVo> tReList = new ArrayList<>();
        //存放相同等级学生，也就是稳定的学生
        List<ClassSementStudentVo> pubList = new ArrayList<>();
        //循环每个学生
        loopStu(sStu,sReList,classSementCompParm,null,null);
        loopStu(tStu,tReList,classSementCompParm,pubList,sReList);
        //计算该等级稳定率
        revo.setStudentVoList(pubList);
        //计算稳定率
        if(sReList.isEmpty()){
            revo.setStableRate("0.0000");
            revo.setDetailVoList(new ArrayList<>());
            return ServiceResponseHandle.success(revo);
        }
        else{
            BigDecimal ssize = new BigDecimal(sReList.size());
            BigDecimal tsize = new BigDecimal(pubList.size());
            revo.setStableRate(tsize.divide(ssize,4,BigDecimal.ROUND_HALF_UP).toString());
        }
        //计算转换率,首先获取所有对比考试各个分数段的学生信息集合
        if(tStu.isEmpty()){
            return ServiceResponseHandle.success(revo);
        }
        else{
            Map<String,ClassSementCompDetailVo> map = new HashMap<>();
            loopStuToMap(tStu,classSementCompParm,map,sReList);
            List<ClassSementCompDetailVo> rere = new ArrayList<>();
            //循环map，计算转换率
            BigDecimal ssize = new BigDecimal(sReList.size());
            map.forEach((k,v)->{
                List<ClassSementStudentVo> lsi = v.getStudentVoList();
                if(!lsi.isEmpty()){
                    BigDecimal tsize = new BigDecimal(lsi.size());
                    v.setChangeRate(tsize.divide(ssize,4,BigDecimal.ROUND_HALF_UP).toString());
                    rere.add(v);
                }
            });
            revo.setDetailVoList(rere);
        }
        return ServiceResponseHandle.success(revo);
    }

    /**
     * 设置返回数据图表对比分析数据
     * @param sourceSele
     * @param targetSele
     * @param revo
     */
    public Boolean calStuTable(SeleExamStudentScoreCalModel sourceSele,SeleExamStudentScoreCalModel targetSele,ClassSementCompVo revo,ClassSementCompParm classSementCompParm){
        Boolean re = true;
        List<SeleProportion> sourceL = sourceSele.getSeleProportionClassList();
        List<SeleProportion> targetL = targetSele.getSeleProportionClassList();
        if(sourceL==null||sourceL.size()==0||targetL==null||targetL.size()==0){
            return false;
        }
        List<String> seName = new ArrayList<>();
        List<Integer> soNum = new ArrayList<>();
        addNumAndName(seName,soNum,sourceL,classSementCompParm,true);
        List<Integer> taNum = new ArrayList<>();
        addNumAndName(seName,taNum,targetL,classSementCompParm,false);
        String[] seN = new String[seName.size()];
        Integer[] soA = new Integer[soNum.size()];
        Integer[] taA = new Integer[taNum.size()];
        revo.setSementName(seName.toArray(seN));
        revo.setSourceArray(soNum.toArray(soA));
        revo.setTargetArray(taNum.toArray(taA));
        return re;
    }

    /**
     * 组装表格数据
     * @param seName
     * @param soNum
     * @param l
     * @param
     */
    public void addNumAndName(List<String> seName,List<Integer> soNum,List<SeleProportion> l,ClassSementCompParm classSementCompParm,Boolean isComp){
        l = l.stream().filter(s->classSementCompParm.getSubjectId().equals(s.getSubjectId())).collect(Collectors.toList());
        l.sort((s1,s2)->s1.getSelectValueName().compareTo(s2.getSelectValueName()));
        for(int i = 0;i<l.size();i++){
            SeleProportion s = l.get(i);
            soNum.add(s.getCount());
            if(isComp){
                seName.add(s.getSelectValueName());
            }
            else{
                if(i>=seName.size()){
                    seName.add(s.getSelectValueName());
                }
            }
        }
    }
    /**
     * 分组各个分数段的学生详情
     * @param tStu
     * @param classSementCompParm
     */
    public void loopStuToMap(List<SeleStudentScoreCalModel> tStu,ClassSementCompParm classSementCompParm,Map<String,ClassSementCompDetailVo> map,List<ClassSementStudentVo> sReList){
        for (SeleStudentScoreCalModel ttu:tStu) {
            //判断该学生是否是源分数段学生，如果不是，则跳过循环
            List<ClassSementStudentVo> l = sReList.stream().filter(sr->ttu.getStudentId().equals(sr.getStudentID())).collect(Collectors.toList());
            if(!l.isEmpty()){
                List<SeleSubujectScoreCalModel> stuD = new ArrayList<>();
                if("0".equals(classSementCompParm.getSubjectId())){
                    if(!classSementCompParm.getSegmentName().equals(ttu.getSelectValueName())){
                        SeleSubujectScoreCalModel s = new SeleSubujectScoreCalModel();
                        s.setScore(ttu.getTotalScore());
                        s.setSubjectName("总分");
                        s.setSelectValueName(ttu.getSelectValueName());
                        stuD.add(s);
                    }
                }
                else{
                    stuD = ttu.getSeleSubujectScoreList();
                    stuD = stuD.stream().filter(s->classSementCompParm.getSubjectId().equals(s.getSubjectId())&&!classSementCompParm.getSegmentName().equals(s.getSelectValueName())).collect(Collectors.toList());
                }
                if(!stuD.isEmpty()){
                    for (SeleSubujectScoreCalModel s:stuD) {
                        ClassSementCompDetailVo devo = map.get(s.getSelectValueName());
                        if(devo==null){
                            devo = new ClassSementCompDetailVo();
                            devo.setChangeName(classSementCompParm.getSegmentName()+"->"+s.getSelectValueName());
                        }
                        List<ClassSementStudentVo> studentVoList = devo.getStudentVoList();
                        if(studentVoList==null){
                            studentVoList = new ArrayList<>();
                        }
                        ClassSementStudentVo v = new ClassSementStudentVo();
                        v.setStudentID(ttu.getStudentId());
                        v.setStudentNo(ttu.getStudentNo());
                        v.setStudentName(ttu.getStudentName());
                        v.setSubjectName(s.getSubjectName());
                        v.setScore(s.getScore());
                        v.setSelectValueName(s.getSelectValueName());
                        studentVoList.add(v);
                        devo.setStudentVoList(studentVoList);
                        map.put(s.getSelectValueName(),devo);
                    }
                }
            }
        }
    }
    /**
     * 循环处理学生信息，筛选对比的科目，等级
     */
    public void loopStu(List<SeleStudentScoreCalModel> tStu,List<ClassSementStudentVo> list,ClassSementCompParm classSementCompParm,List<ClassSementStudentVo> pubList,List<ClassSementStudentVo> sou){
        for (SeleStudentScoreCalModel ttu:tStu) {
            List<SeleSubujectScoreCalModel> stuD = new ArrayList<>();
            if("0".equals(classSementCompParm.getSubjectId())){
                if(classSementCompParm.getSegmentName().equals(ttu.getSelectValueName())){
                    SeleSubujectScoreCalModel s = new SeleSubujectScoreCalModel();
                    s.setScore(ttu.getTotalScore());
                    s.setSubjectName("总分");
                    stuD.add(s);
                }
            }
            else{
                stuD = ttu.getSeleSubujectScoreList();
                stuD = stuD.stream().filter(s->classSementCompParm.getSubjectId().equals(s.getSubjectId())&&classSementCompParm.getSegmentName().equals(s.getSelectValueName())).collect(Collectors.toList());
            }
            if(stuD!=null&&stuD.size()==1){
                SeleSubujectScoreCalModel se = stuD.get(0);
                ClassSementStudentVo v = new ClassSementStudentVo();
                v.setSelectValueName(classSementCompParm.getSegmentName());
                v.setScore(se.getScore());
                v.setStudentName(ttu.getStudentName());
                v.setSubjectName(se.getSubjectName());
                v.setStudentNo(ttu.getStudentNo());
                v.setStudentID(ttu.getStudentId());
                list.add(v);
                if(pubList!=null){
                    List<ClassSementStudentVo> comp = sou.stream().filter(so->v.getStudentID().equals(so.getStudentID())).collect(Collectors.toList());
                    if(!comp.isEmpty()){
                        pubList.add(v);
                    }
                }
            }
        }
    }
    /**
     * 班级分析分数段统计学生列表
     * @param scoreSementParm
     * @return
     */
    public ServiceResponse classSementStudent(ClassSementParm sementParm){
        Map<String, Object> queryMap = new HashedMap<>();
        if (sementParm != null && StringUtils.isNotEmpty(sementParm.getExamId()))
            queryMap.put("examId", sementParm.getExamId());
        if (sementParm != null && StringUtils.isNotEmpty(sementParm.getGradeId()))
            queryMap.put("gradeId", sementParm.getGradeId());
        if (sementParm != null && StringUtils.isNotEmpty(sementParm.getClassId()))
            queryMap.put("classId", sementParm.getClassId());

        SeleStudentScoreCalVO bean = new SeleStudentScoreCalVO();
        Map<String, String> filedAlias= FiledAliasMapUtils.java2Map(bean,"seleStudentScore");
        /* Map<String, String> filedAliasMap = new HashMap<>();*/
        // Map<String, String> filedAliasMap = FiledAliasMapUtils.java2Map(bean, "seleStudentScoreList");
        filedAlias.put("seleStudentScoreList", "seleStudentScore");
        SpringDataPageable pageable = new SpringDataPageable(sementParm.getPageIndex(), sementParm.getPageSize());
        Page<SeleStudentScoreCalVO> page = seleExamStudentScoreRepsitory.findNestPage(queryMap, filedAlias,null, "seleStudentScore","seleStudentScore.studentId", null,
                SeleExamStudentScoreCalModel.class, SeleStudentScoreCalVO.class);
        List<SeleStudentScoreCalVO> list = page.getContent();
        List<ClassSementStudentVo> reList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(list)){
            list.forEach(seleStudentScoreCalVO -> {
                SeleStudentScoreCalModel seleStudentScore = seleStudentScoreCalVO.getSeleStudentScore();
                List<SeleSubujectScoreCalModel> seleSubujectScoreCalModels = seleStudentScoreCalVO.getSeleStudentScore().getSeleSubujectScoreList();
                List<SeleSubujectScoreCalModel> seleSubujectScoreCalModelList = seleSubujectScoreCalModels.stream().filter(e-> e.getSubjectId().equals(sementParm.getSubjectId())).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(seleSubujectScoreCalModelList)){
                    SeleSubujectScoreCalModel seleSubujectScoreCalModel = seleSubujectScoreCalModelList.get(0);
                    ClassSementStudentVo revo = new ClassSementStudentVo();
                    revo.setStudentName(seleStudentScore.getStudentName());
                    revo.setStudentNo(seleStudentScore.getStudentNo());
                    revo.setSubjectName(seleSubujectScoreCalModel.getSubjectName());
                    revo.setScore(seleSubujectScoreCalModel.getScore());
                    revo.setSelectValueName(seleSubujectScoreCalModel.getSelectValueName());
                    reList.add(revo);
                }
            });
        }
        return ServiceResponseHandle.success(reList);
    }

    @Override
    public Page<ScoreFootFaultVo> getScoreFootFault(ScoreSementParm sementParm) {
        Map<String, Object> queryMap = new HashedMap<>();
        if (sementParm != null && StringUtils.isNotEmpty(sementParm.getExamId()))
            queryMap.put("examId", sementParm.getExamId());
        if (sementParm != null && StringUtils.isNotEmpty(sementParm.getSchoolId()))
            queryMap.put("schoolId", sementParm.getSchoolId());
        if (sementParm != null && StringUtils.isNotEmpty(sementParm.getGradeId()))
            queryMap.put("gradeId", sementParm.getGradeId());
        if (sementParm != null && StringUtils.isNotEmpty(sementParm.getClassId()))
            queryMap.put("classId", sementParm.getClassId());
        SeleStudentScoreCalVO bean = new SeleStudentScoreCalVO();
        Map<String, String> filedAlias= FiledAliasMapUtils.java2Map(bean,"seleStudentScore");
        filedAlias.put("seleStudentScoreList", "seleStudentScore");
        SpringDataPageable pageable = new SpringDataPageable(sementParm.getPageIndex(), sementParm.getPageSize());
        Page<SeleStudentScoreCalVO> page = seleExamStudentScoreRepsitory.findNestPage(queryMap, filedAlias,null, "seleStudentScore","seleStudentScore.studentId", null,
                SeleExamStudentScoreCalModel.class, SeleStudentScoreCalVO.class);
        List<SeleStudentScoreCalVO> list = page.getContent();
        List<ScoreFootFaultVo> scoreSegmentList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (SeleStudentScoreCalVO seleExam : list) {
                List<SubjectFootScoreVo> subjectScoreList = new ArrayList<>();
                SeleStudentScoreCalModel seleExamStudentScore = seleExam.getSeleStudentScore();
                if(seleExamStudentScore.getFootFault() ==null){
                    continue;
                }
                ScoreFootFaultVo scoreSegment = new ScoreFootFaultVo();
                if (seleExamStudentScore != null) {
                    scoreSegment.setStudentName(seleExamStudentScore.getStudentName());
                    scoreSegment.setStudentNo(seleExamStudentScore.getStudentNo());
                    scoreSegment.setAverageScore(seleExamStudentScore.getTotalAvg());
                    scoreSegment.setTotalScore(seleExamStudentScore.getTotalScore());
                    scoreSegment.setStudentId(seleExamStudentScore.getStudentId());
                    List<SeleSubujectScoreCalModel> seleStudentScoreList = seleExamStudentScore.getSeleSubujectScoreList();
                    if (CollectionUtils.isNotEmpty(seleStudentScoreList)) {
                        for (SeleSubujectScoreCalModel seleStudentScore : seleStudentScoreList) {
                            SubjectFootScoreVo subjectScore = new SubjectFootScoreVo();
                            subjectScore.setSubjectId(seleStudentScore.getSubjectId());
                            subjectScore.setScore(seleStudentScore.getScore());
                            subjectScore.setSubjectName(seleStudentScore.getSubjectName());
                            subjectScore.setFootFalultType(seleStudentScore.getTypeName());
                            subjectScore.setFootFault(seleStudentScore.getFootFaultName());
                            subjectScoreList.add(subjectScore);
                        }
                    }
                }
                scoreSegment.setSubjectScores(subjectScoreList);
                scoreSegment.setFootFault(seleExamStudentScore.getFootFaultName());
                scoreSegment.setFootFalultType(seleExamStudentScore.getTypeName());
                scoreSegmentList.add(scoreSegment);

            }
        }
        Page<ScoreFootFaultVo> pages = new PageImpl<ScoreFootFaultVo>(scoreSegmentList, pageable, page.getTotalElements());
        return pages;
    }

    /**
     * 班级知识点 得分失分对比
     * @param classSementCompParm
     * @return
     */
    @Override
    public ServiceResponse<?> classKnowledgeCompare(ClassSementCompParm classSementCompParm) {
        // 现获取到所有参考的科目
        List<ExamPaperModel> exampaperList = this.examPaperRepsitory.findByExamidAndGradeid(classSementCompParm.getSourceExamId(), classSementCompParm.getGradeId());
        List<SubjectVo> subjectVos = new ArrayList<>();
        Map<String,Object> resultMap = new HashMap<>();
        if(CollectionUtils.isNotEmpty(exampaperList)){
            exampaperList.forEach(examPaperModel -> {
                SubjectVo subjectVo = new SubjectVo();
                subjectVo.setSubjectId(examPaperModel.getSubjectid());
                subjectVo.setSubjectName(examPaperModel.getSubjectname());
                subjectVos.add(subjectVo);
            });
            if(StringUtils.isBlank(classSementCompParm.getSubjectId())){
                classSementCompParm.setSubjectId(subjectVos.get(0).getSubjectId());
            }
            Map<String,Object> paramMap = new HashMap<>();
            paramMap.put("examId",classSementCompParm.getSourceExamId());
            paramMap.put("gradeId",classSementCompParm.getGradeId());
            paramMap.put("classId",classSementCompParm.getClassId());
            paramMap.put("subjectId",classSementCompParm.getSubjectId());
            ExamSubjectStuPointCalModel examSubjectStuPointCalModel = this.pointRepsitory.findUniqueBy(paramMap);
            //获得所有的知识点
            List<String> pointNames = new ArrayList<>();
            List<Double> totalScore = new ArrayList<>();
            List<Double> receveScore = new ArrayList<>();
            List<Double> loseScore = new ArrayList<>();
            if(examSubjectStuPointCalModel !=null){
                List<PointCalModel> pointList = examSubjectStuPointCalModel.getPointList();
                List<PointCalModel> collect = pointList.stream().sorted((e1, e2) ->
                        BigDecimalUtils.convertsToInt(BigDecimalUtils.mul(e2.getScore(),e2.getClassReceAvgRate(),1))
                                - BigDecimalUtils.convertsToInt(BigDecimalUtils.mul(e1.getScore(),e1.getClassReceAvgRate(),1))).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(collect)){
                    collect.forEach(pointCalModel -> {
                        pointNames.add(pointCalModel.getPointName());
                        totalScore.add(BigDecimalUtils.round(new BigDecimal(pointCalModel.getScore()),2).doubleValue());
                        receveScore.add(BigDecimalUtils.mul(pointCalModel.getScore(),pointCalModel.getClassReceAvgRate(),2));
                        loseScore.add(BigDecimalUtils.mul(pointCalModel.getScore(),pointCalModel.getClassLoseAvgRate(),2));
                    });
                }
            }
            resultMap.put("subject",subjectVos);
            resultMap.put("pointNames",pointNames);
            resultMap.put("receveScore",receveScore);
            resultMap.put("loseScore",loseScore);
            resultMap.put("totalScore",totalScore);
            return ServiceResponseHandle.success(resultMap);
        }
        return ServiceResponseHandle.failed("没查询到数据");
    }

    /**
     *
     * @param classSementCompParm
     * @return
     */
    @Override
    public ServiceResponse<?> classExamCompare(ClassSementCompParm classSementCompParm) {
        List<ExamPaperModel> exampaperList = this.examPaperRepsitory.findByExamidAndGradeid(classSementCompParm.getSourceExamId(), classSementCompParm.getGradeId());
        List<SubjectVo> subjectVos = new ArrayList<>();
        Map<String,Object> resultMap = new HashMap<>();
        if(CollectionUtils.isNotEmpty(exampaperList)) {
            exampaperList.forEach(examPaperModel -> {
                SubjectVo subjectVo = new SubjectVo();
                subjectVo.setSubjectId(examPaperModel.getSubjectid());
                subjectVo.setSubjectName(examPaperModel.getSubjectname());
                subjectVos.add(subjectVo);
            });
            Map<String,Object> paramMap = new HashMap<>();
            paramMap.put("examId",classSementCompParm.getSourceExamId());
            paramMap.put("gradeId",classSementCompParm.getGradeId());
            paramMap.put("classId",classSementCompParm.getClassId());
            paramMap.put("subjectId",classSementCompParm.getSubjectId());
            ExamSubjectStuPointCalModel source = this.pointRepsitory.findUniqueBy(paramMap);

            // 判断是历史对比 班级对比
            Map<String,Object> targetParamMap = new HashMap<>();
            if ((GlobalTypeEnum.HISTORY_COMPARE.getCode()+"").equals(classSementCompParm.getType())){
                targetParamMap.put("examId",classSementCompParm.getTargetExamId());
                targetParamMap.put("gradeId",classSementCompParm.getGradeId());
                targetParamMap.put("classId",classSementCompParm.getClassId());
            }else{
                targetParamMap.put("classId",classSementCompParm.getTargetClassId());
                targetParamMap.put("examId",classSementCompParm.getSourceExamId());
                targetParamMap.put("gradeId",classSementCompParm.getGradeId());
            }
            targetParamMap.put("subjectId",classSementCompParm.getSubjectId());

            ExamSubjectStuPointCalModel target = this.pointRepsitory.findUniqueBy(targetParamMap);
            //获得所有的知识点
            resultMap = this.getPointList(source, target);
            resultMap.put("subject",subjectVos);
            return ServiceResponseHandle.success(resultMap);
        }
        return ServiceResponseHandle.failed("没查询到数据");
    }
    private Map<String,Object> getPointList(ExamSubjectStuPointCalModel source,ExamSubjectStuPointCalModel target){
        List<Double> receveScoreSource = new ArrayList<>();
        List<Double> receveScoreTarget = new ArrayList<>();
        List<String> knowledgeName = new ArrayList<>();
        List<PointCalModel> collect = null;
        if(target !=null){
            Map<String, Double> sourceMap =source.getPointList()
                    .stream().collect(Collectors.toMap(PointCalModel::getPointId, e -> e.getClassReceAvgRate()));
            Map<String, Double> filterdTargetMap = target.getPointList()
                    .stream().filter(e -> sourceMap.get(e.getPointId()) != null)
                    .collect(Collectors.toMap(PointCalModel::getPointId, e -> e.getClassReceAvgRate()));
            collect = source.getPointList()
                    .stream().filter(e -> filterdTargetMap.get(e.getPointId()) != null).collect(Collectors.toList());
            filterdTargetMap.forEach((k,v)->{
                receveScoreTarget.add(BigDecimalUtils.round(new BigDecimal(v),2).doubleValue());
            });
        }else{
            collect = source.getPointList();
        }
        collect.forEach(e->{
            receveScoreSource.add(BigDecimalUtils.round(new BigDecimal(e.getClassReceAvgRate()),2).doubleValue());
            knowledgeName.add(e.getPointName());
        });
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("receveScoreTarget",receveScoreTarget);
        resultMap.put("receveScoreSource",receveScoreSource);
        resultMap.put("knowledgeName",knowledgeName);
        Map<String,Object> examMap = new HashMap<>();
        examMap.put("sourceExamName",source.getExamName());
        examMap.put("targetExamName",target !=null ? target.getExamName():"");
        resultMap.put("examName",examMap);
        return resultMap;
    }
    /**
     *  根据类型选择考试或者班级
     * @param segementParam
     * @return
     */
    @Override
    public ServiceResponse<?> getClassOrExam(SegementParam segementParam) {
        if(segementParam == null)
            return ServiceResponseHandle.failed("参数不能为空");
        //考试对比
        if("0".equals(segementParam.getType())){
            Map<String,Object> paramMap = new HashMap<>();
            paramMap.put("gradeId",segementParam.getGradeId());
            paramMap.put("classId",segementParam.getClassId());
            List<ExamStudentScoreCalModel> examStudentScoreCalModels = this.examStuScoRepsitory.findListBy(paramMap);
            if(CollectionUtils.isNotEmpty(examStudentScoreCalModels)){
                examStudentScoreCalModels = examStudentScoreCalModels.stream().filter(e -> !e.getExamId().equals(segementParam.getExamId())).collect(Collectors.toList());
            }
            List<Map<String,Object>> list = new ArrayList<>();
            if(CollectionUtils.isNotEmpty(examStudentScoreCalModels)){
                examStudentScoreCalModels.forEach(examStudentScoreCalModel -> {
                    Map<String,Object> objMap = new LinkedHashMap<>();
                    objMap.put("objectId",examStudentScoreCalModel.getExamId());
                    objMap.put("objectName",examStudentScoreCalModel.getExamName());
                    list.add(objMap);
                });
            }
            return ServiceResponseHandle.success(list);
        }else{
        // 班级对比
            Map<String,Object> paramMap = new HashMap<>();
            paramMap.put("examId",segementParam.getExamId());
            paramMap.put("gradeId",segementParam.getGradeId());
            List<ExamStudentScoreCalModel> examStudentScoreCalModels = this.examStuScoRepsitory.findListBy(paramMap);
            if(CollectionUtils.isNotEmpty(examStudentScoreCalModels)){
                examStudentScoreCalModels = examStudentScoreCalModels.stream().filter(e -> !e.getClassId().equals(segementParam.getClassId())).collect(Collectors.toList());
            }
            List<Map<String,Object>> list = new ArrayList<>();
            if(CollectionUtils.isNotEmpty(examStudentScoreCalModels)){
                examStudentScoreCalModels.forEach(examStudentScoreCalModel -> {
                    Map<String,Object> objMap = new LinkedHashMap<>();
                    objMap.put("objectId",examStudentScoreCalModel.getClassId());
                    objMap.put("objectName",examStudentScoreCalModel.getClassName());
                    list.add(objMap);
                });
            }
            return ServiceResponseHandle.success(list);
        }
    }

    /**
     *  成绩列表查看下载表格
     * @param scoreSementParm
     * @return
     */
    @Override
    public void scoreSegementDownload(ExamStudentScoreCalModel scoreSementParm, HttpServletResponse response) {
        String titlesFirst = "姓名,学号,";
        String titlesEnd = ",平均分,总分,班级排名";
        Page<ExamStudentScoreCalModel> studentScore = this.studentScoreService.getStudentScore(scoreSementParm, 1, 15);
        if(studentScore !=null){
            List<ExamStudentScoreCalModel> examStudentScoreCalModels = studentScore.getContent();
            List<ScoreExcelVo> scoreExcelVoList = new ArrayList<>();
            if(CollectionUtils.isNotEmpty(examStudentScoreCalModels)){
                ExamStudentScoreCalModel examStudentScoreCalModel = examStudentScoreCalModels.get(0);
                List<StudentScoreCalModel> studentScoreList = examStudentScoreCalModel.getStudentScoreList();
                List<String> subjectNames = new ArrayList<>();
                studentScoreList.get(0).getSubujectScoreList().forEach(e->{subjectNames.add(e.getSubjectName());});
                List<String> titles = this.getTitles(subjectNames, titlesFirst, titlesEnd);
                studentScoreList.forEach(stu->{
                    ScoreExcelVo scoreExcelVo = new ScoreExcelVo();
                    scoreExcelVo.setStudentName(stu.getStudentName());
                    scoreExcelVo.setStudentNo(stu.getStudentNo());
                    scoreExcelVo.setTotalScore(stu.getTotalScore());
                    scoreExcelVo.setAverageScore(stu.getTotalAvg());
                    scoreExcelVo.setClassSortNum(stu.getClassSortNum());
                    List<Double> scores = new ArrayList<>();
                    stu.getSubujectScoreList().forEach(subject->{
                        scores.add(subject.getScore());
                    });
                    scoreExcelVo.setSubjectScore(scores);
                    scoreExcelVoList.add(scoreExcelVo);
                });
                logger.info("表头参数为：{}", JSONObject.toJSONString(titles));
                logger.info("具体参数为：{}", JSONObject.toJSONString(scoreExcelVoList));
                HSSFWorkbook data = ExcelUtil.createExcel("查看成绩列表导出", titles, scoreExcelVoList, false);
                ExcelUtil.download("查看成绩列表导出",data,response);
            }
        }
    }

    /**
     *  分数段列表导出
     * @param scoreSementParm
     * @return
     */
    @Override
    public void scoreSectionDownload(ScoreSementParm scoreSementParm,HttpServletResponse response) {
        String titlesFirst = "姓名,学号,";
        String titlesEnd = ",平均分,总分,分数段";
        Page<ScoreSegmentVo> segment = this.getSegment(scoreSementParm);
        List<ScoreSegmentVo> scoreSegmentVos = segment.getContent();
        if(CollectionUtils.isNotEmpty(scoreSegmentVos)){
            List<ScoreSectionExcelVo> scoreSectionExcelVoList = new ArrayList<>();
            List<SubjectScoreVo> subjectScores = scoreSegmentVos.get(0).getSubjectScores();
            List<String> subjectName = new ArrayList<>();
            subjectScores.forEach(e->{subjectName.add(e.getSubjectName());});
            List<String> titles = this.getTitles(subjectName, titlesFirst, titlesEnd);
            scoreSegmentVos.forEach(scoreSegmentVo -> {
                ScoreSectionExcelVo scoreSectionExcelVo = new ScoreSectionExcelVo();
                scoreSectionExcelVo.setStudentName(scoreSegmentVo.getStudentName());
                scoreSectionExcelVo.setStudentNo(scoreSegmentVo.getStudentNo());
                scoreSectionExcelVo.setAverageScore(scoreSegmentVo.getAverageScore());
                scoreSectionExcelVo.setTotalScore(scoreSegmentVo.getTotalScore());
                scoreSectionExcelVo.setSelectValueName(scoreSegmentVo.getScoreState());
                List<Double> scores = new ArrayList<>();
                scoreSegmentVo.getSubjectScores().forEach(subject->{
                    scores.add(subject.getScore());
                });
                scoreSectionExcelVo.setSubjectScore(scores);
                scoreSectionExcelVoList.add(scoreSectionExcelVo);
            });
            logger.info("表头参数为：{}", JSONObject.toJSONString(titles));
            logger.info("具体参数为：{}", JSONObject.toJSONString(scoreSectionExcelVoList));
            HSSFWorkbook data = ExcelUtil.createExcel("分数段列表导出", titles, scoreSectionExcelVoList, false);
            ExcelUtil.download("分数段列表导出",data,response);
        }
    }

    /**
     *
     *  踩线生列表导出
     * @param scoreSementParm
     * @return
     */
    @Override
    public void stepLineDownload(ScoreSementParm scoreSementParm,HttpServletResponse response) {
        String titlesFirst = "姓名,学号,";
        String titlesEnd = ",平均分,总分,踩线,类别";
        Page<ScoreFootFaultVo> segment = this.getScoreFootFault(scoreSementParm);
        List<ScoreFootFaultVo> scoreSegmentVos = segment.getContent();
        if(CollectionUtils.isNotEmpty(scoreSegmentVos)){
            List<StepLineExcelVo> scoreSectionExcelVoList = new ArrayList<>();
            List<SubjectFootScoreVo> subjectScores = scoreSegmentVos.get(0).getSubjectScores();
            List<String> subjectNames = new ArrayList<>();
            subjectScores.forEach(e->{subjectNames.add(e.getSubjectName());});
            List<String> titles = this.getTitles(subjectNames, titlesFirst, titlesEnd);
            scoreSegmentVos.forEach(scoreSegmentVo -> {
                StepLineExcelVo stepLineExcelVo = new StepLineExcelVo();
                stepLineExcelVo.setStudentName(scoreSegmentVo.getStudentName());
                stepLineExcelVo.setStudentNo(scoreSegmentVo.getStudentNo());
                stepLineExcelVo.setAverageScore(scoreSegmentVo.getAverageScore());
                stepLineExcelVo.setTotalScore(scoreSegmentVo.getTotalScore());
                stepLineExcelVo.setStepLineName(scoreSegmentVo.getFootFault());
                stepLineExcelVo.setTypeName(scoreSegmentVo.getFootFalultType());
                List<Double> scores = new ArrayList<>();
                scoreSegmentVo.getSubjectScores().forEach(subject->{
                    scores.add(subject.getScore());
                });
                stepLineExcelVo.setSubjectScore(scores);
                scoreSectionExcelVoList.add(stepLineExcelVo);
            });
            logger.info("表头参数为：{}", JSONObject.toJSONString(titles));
            logger.info("具体参数为：{}", JSONObject.toJSONString(scoreSectionExcelVoList));
            HSSFWorkbook data = ExcelUtil.createExcel("踩线生列表导出", titles, scoreSectionExcelVoList, false);
            ExcelUtil.download("踩线生列表导出",data,response);
        }
    }

  /**
   *  按科目导出
   * @param classSementParm
   * @param response
   */
  @Override
  public void classSementStudentDownload(ClassSementParm classSementParm, HttpServletResponse response) {
    ServiceResponse serviceResponse = this.classSementStudent(classSementParm);
    if(serviceResponse.isSuccess() && serviceResponse.getData() !=null){
      List<ClassSementStudentVo> classSementStudentVoList = (List<ClassSementStudentVo>)serviceResponse.getData();
      if(CollectionUtils.isNotEmpty(classSementStudentVoList)){
        List<ClassSementStudentExcelVo> classSementStudentExcelVos = new ArrayList<>();
        String[] titles = {"姓名","学号","科目","成绩","分数段"};
        classSementStudentVoList.forEach(student->{
            ClassSementStudentExcelVo classSementStudentExcelVo = new ClassSementStudentExcelVo();
            classSementStudentExcelVo.setStudentName(student.getStudentName());
            classSementStudentExcelVo.setStudentNo(student.getStudentNo());
            classSementStudentExcelVo.setSubjectName(student.getSubjectName());
            classSementStudentExcelVo.setScore(student.getScore()+"");
            classSementStudentExcelVo.setSelectValueName(student.getSelectValueName());
            classSementStudentExcelVos.add(classSementStudentExcelVo);
        });
        HSSFWorkbook data = ExcelUtil.createExcel("班级分析分数段列表导出", Arrays.asList(titles), classSementStudentExcelVos, false);
        ExcelUtil.download("班级分析分数段列表导出",data,response);


      }
    }
  }


  private List<String> getTitles(List<String> subjectScoreVoList,String titleFirst,String titleEnd){
        if(CollectionUtils.isNotEmpty(subjectScoreVoList)){
            StringBuffer subjectName = new StringBuffer();
            subjectScoreVoList.forEach(sub->{
                subjectName.append(sub+",");
            });
            String subjectNameNew = subjectName.substring(0,subjectName.lastIndexOf(","));
            subjectNameNew = titleFirst + subjectNameNew + titleEnd;
            return  Arrays.asList(subjectNameNew.split(","));
        }
        logger.info("参数异常");
        return null;
    }

}
